{% extends "base.html" %}
{% block title %}Technical Details - {% endblock %}
{% block content %}
<div class="container">
  <div class="grid grid-center">
    <div class="column-12">
    <h2>StoryMapJS for Technical Users</h2>
    <p>Most users will probably use the <a href="{{ url_for('select') }}">StoryMapJS authoring tool</a> to create their StoryMaps. But if you want maximum control over StoryMapJS, read on.</p>
    <h3>Managing StoryMapJS data</h3>
    <p>StoryMapJS uses JSON data as its native data format. You can load the data from a file on the web, or you can create a javascript object by any other means you like.  If you are loading the data from a URL, it must either be on the same server as the page where you are displaying the StoryMap or from a server with correctly configured CORS headers. (The details of cross-domain origin restrictions are out of scope for this document.)</p>
    <p>Complete details on the JSON syntax for StoryMapJS is <a href="#json-syntax">below</a>.</p>
    <h3>Setting up your page</h3>
    <p>You'll need to include code something like the following.
      <pre class="prettyprint">
&lt;!-- The StoryMap container can go anywhere on the page. Be sure to
    specify a width and height.  The width can be absolute (in pixels) or
    relative (in percentage), but the height must be an absolute value.
    Of course, you can specify width and height with CSS instead --&gt;
&lt;div id="mapdiv" style="width: 100%; height: 600px;"&gt;&lt;/div&gt;

&lt;!-- Your script tags should be placed before the closing body tag. --&gt;
&lt;link rel="stylesheet" href="https://cdn.knightlab.com/libs/storymapjs/latest/css/storymap.css"&gt;
&lt;script type="text/javascript" src="https://cdn.knightlab.com/libs/storymapjs/latest/js/storymap-min.js"&gt;&lt;/script&gt;

&lt;script&gt;
// storymap_data can be an URL or a Javascript object
var storymap_data = '{{ STATIC_URL }}demo/demo.json';

// certain settings must be passed within a separate options object
var storymap_options = {};

var storymap = new VCO.StoryMap('mapdiv', storymap_data, storymap_options);
window.onresize = function(event) {
    storymap.updateDisplay(); // this isn't automatic
}
&lt;/script&gt;
      </pre>
    </p>
    <p>When creating a StoryMap object, certain settings, if you wish to override the defaults, may be passed within the separate options parameter. However, as of StoryMap 0.4.6, you can also specify these directly in the <code>storymap_data</code> JSON, as "top-level" keys.
        <ul>
            <li>map_type</li>
            <li>map_subdomains</li>
            <li>map_as_image</li>
            <li>map_background_color</li>
            <li>language</li>
            <li>zoomify</li>
            <li>calculate_zoom</li>
            <li>call_to_action</li>
            <li>call_to_action_text</li>
        </ul>
    </p>
    <p>Also, any specified fonts must be loaded by the embedding page.  View the <a href="https://github.com/NUKnightLab/StoryMapJS/blob/master/source/embed/index.html">StoryMap embed tool source code</a> for details.</p>
    <h3 id="json-syntax">JSON syntax</h3>
    <p>StoryMapJS is still in beta, so the JSON format is subject to change. Most changes should be additions, providing backward compatibility.</p>
    <p><strong>Map-based storymaps</strong> tell stories with geographic locations.  The JSON for these StoryMaps have the following structure:
      <pre class="prettyprint">
{
    width: <em>integer</em>,                // required for embed tool; width of StoryMap
    height: <em>integer</em>,               // required for embed tool; height of StoryMap
    font_css: <em>string</em>,              // optional; font set
    calculate_zoom: <em>true</em>,              // optional; defaults to true.
    storymap: {
        language: <em>string</em>,          // required; two-letter ISO language code
        map_type: <em>string</em>,          // required
        map_as_image: false,       // required
        map_subdomains: <em>string</em>,    // optional
        slides: [<em>object</em>]           // required; array of slide objects (see below)
    }
}
      </pre>
    </p>
    <p>
        <code>map_type</code> may be either a custom URL tile template <a href="http://leafletjs.com/reference.html#tilelayer" target="_blank">as described in the Leaflet documentation</a> or one of the following coded values:
        <ul>
        <li><code>stamen:toner-lite</a></code> - the default</li>
        <li><code>stamen:toner</a></code> - high-contrast black and white <a href="http://maps.stamen.com/toner/#16/42.0502/-87.6746" target="_blank" title="example"><i class="icon-external-link"></i></a></li>
        <li><code>stamen:toner-lines</code> - just the lines (mostly roads) from the Toner style <a href="http://maps.stamen.com/toner-lines/#16/42.0502/-87.6746" target="_blank" title="example"><i class="icon-external-link"></i></a></li>
        <li><code>stamen:toner-labels</code> - just the labels (place names and roads) from the Toner style <a href="http://maps.stamen.com/toner-labels/#16/42.0502/-87.6746" target="_blank" title="example"><i class="icon-external-link"></i></a></li>
        <li><code>stamen:watercolor</code> - an artistic representation <a href="http://maps.stamen.com/watercolor/#16/42.0502/-87.6746" target="_blank" title="example"><i class="icon-external-link"></i></a></li>
        <li><code>osm:standard</code> - maps used by OpenStreetMap <a href="http://www.openstreetmap.org/#map=16/42.0502/-87.6746" target="_blank" title="example"><i class="icon-external-link"></i></a></li>
        <li><code>mapbox:<em>map-id</em></code> - replace <em>map-id</em> with a <a href="https://www.mapbox.com/help/define-map-id/">Mapbox Map ID</a> (requires a <a href="https://www.mapbox.com/">MapBox account</a>)</li>
        </ul>
    </p>
    <p><code>map_subdomains</code> is only relevant if you specify a custom URL tile template.  If needed, it should be specified as a single string, where each character is a valid subdomain substitution (e.g. "abc").</p>
    <p><code>calculate_zoom</code> is optional. StoryMapJS will compute the optimal zoom level for each of your slides so as to keep both the previous and the next map point visible. If you'd rather control the zoom level for each slide, set the <code>calculate_zoom</code> option to <code>false</code> and then be sure to set the <code>zoom</code> property for each slide.</p>
    <p><strong>Gigapixel StoryMaps</strong> tell stories using large, high-resolution images.  The JSON for these StoryMaps have the following structure:
      <pre class="prettyprint">
{
    width: <em>integer</em>,                    // required for embed tool; width of StoryMap
    height: <em>integer</em>,                   // required for embed tool; height of StoryMap
    font_css: <em>string</em>,                  // optional; font set for UI controls/messages
    calculate_zoom: <em>true</em>,              // optional; defaults to true *unless* map_as_image is true.
    storymap: {
        language: <em>string</em>,              // required; two-letter ISO language code
        map_type: "zoomify",           // required
        map_as_image: <em>boolean</em>,         // required; omit connecting lines between slide locations
        map_background_color: <em> string</em>, // optional; hexadecimal color value for map background
        zoomify: {
            path: <em>string</em>,              // required; URL path to zoomable image folder
            width: <em>integer</em>,            // required; maximum width of image
            height: <em>integer</em>,           // required; maximum height of image
            tolerance: <em>decimal</em>         // required; display tolerance
        }
        slides: [<em>object</em>]               // required; array of slide objects (see below)
    }
}
      </pre>
    </p>
    <p><code>map_as_image</code> gives StoryMap a hint about whether your gigapixel image is a map (such as a historic map) or a non-geographic image. When <code>map_as_image</code> is set to <code>true</code>, StoryMap understands that you are using a non-geographic image. It suppresses the line that connects markers, and it implicitly sets the <code>calculate_zoom</code> option to <code>false</code>, which means that you must make sure to set the <code>zoom</code> property for each of your slides.</p>
    <p>For either type of StoryMap:
      <p>The <code>language</code> setting specifies the language for user-interface controls and messages.  Supported codes can be viewed <a href="https://github.com/NUKnightLab/StoryMapJS/tree/master/source/js/language/locale">here</a>.
    </p>
    <p>The <code>font_css</code> value should be specified as an URL to your font CSS file or as "stock:<em>code</em>" (e.g. "stock:amatic-andika").  For an example of how to define a custom font CSS file, see <a href="https://github.com/NUKnightLab/StoryMapJS/tree/master/build/css/fonts">the GitHub repository</a>. The valid values for <em>code</em> above are the parts of the file names in the repository between <code>font.</code> and <code>.css</code>. Examples of the available fonts can be seen <a href="{{ STATIC_URL }}img/font-options.png" target="_blank">in this image</a>.</p>
    <p>Each object with the <code>slides</code> array has the following specification:
      <pre class="prettyprint">
{
    type: "overview",      // optional; if present must be set to "overview"
    location: {            // required for all slides except "overview" slide
        lat: <em>decimal</em>,      // latitude of point on map
        lon: <em>decimal</em>       // longitude of point on map
    },
    text: {                // optional if media present
        headline: <em>string</em>,
        text: <em>string</em>       // may contain HTML markup
    },
    media: {               // optional if text present
        url: <em>string</em>,       // url for featured media
        caption: <em>string</em>,   // optional; brief explanation of media content
        credit: <em>string</em>     // optional; creator of media content
    }
}
      </pre>
    </p>
    <p>It is recommended that your first slide be an "overview" slide.  The map on an overview slide will show the locations of all subsequent slides.</p>
    <p>The media URL can come from a number of different services, including YouTube, Flickr, Vimeo, and Twitter.  You can get an overview of supported media types by looking at the <a href="https://github.com/NUKnightLab/StoryMapJS/blob/master/source/js/media/VCO.MediaType.js">StoryMapJS source code</a>.</p>
    </div>
  </div>
</div>
{% endblock %}

{% block scripts %}
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script>
{% endblock %}
